/* eslint no-console: off */
import path from "path";
import { mkdirSync, existsSync } from "fs";
import simpleGit, { SimpleGit } from "simple-git";
import { ESLint } from "eslint";
import globals from "globals";
import compat from "../src/index";
import {
  parser as typescriptEslintParser,
  plugin as typescriptEslintPlugin,
} from "typescript-eslint";

// @ts-expect-error Missing
import * as babelEslintParser from "@babel/eslint-parser";

export type RepoInfo = {
  // name of repo
  name: string;
  // location to store repo within project
  location: string;
  // where to clone repo from
  remoteLink: string;
  // what version of repo hould be checked out
  targetCommitId: string;
  // related tag for targetCommitId (if it exists)
  targetGitRef?: string;
  // file patterns to lint in repo
  filePatterns: Array<string>;
  // browsers the repo should target (if omitted then uses default browserlist)
  browserslist?: Array<string>;
  // used in new ESLint(options)
  eslintOptions: ESLint.Options;
};

const projectRoot = path.join(__dirname, "..");

const reposDir = "benchmarks-tmp";

const repos: Array<RepoInfo> = [
  {
    name: "bootstrap",
    location: path.join(projectRoot, reposDir, "bootstrap"),
    remoteLink: "https://github.com/twbs/bootstrap.git",
    targetCommitId: "7a6da5e3e7ad7c749dde806546a35d4d4259d965",
    targetGitRef: "v4.5.0",
    filePatterns: [path.join("js", "src"), path.join("js", "tests"), "build"],
    eslintOptions: {
      cwd: path.join(projectRoot, reposDir, "bootstrap"),
      useEslintrc: false,
      // @ts-expect-error Bug?
      baseConfig: [
        compat.configs["flat/recommended"],
        {
          languageOptions: {
            parser: babelEslintParser,
            parserOptions: {
              ecmaVersion: 2022,
              sourceType: "module",
              requireConfigFile: false,
            },
          },
        },
      ],
    },
  },
  {
    name: "electron-react-boilerplate",
    location: path.join(projectRoot, reposDir, "electron-react-boilerplate"),
    remoteLink:
      "https://github.com/electron-react-boilerplate/electron-react-boilerplate.git",
    targetCommitId: "c240ecabaffb3ddfcb32c7b1970eedb4027caeec",
    targetGitRef: "v1.1.0",
    filePatterns: ["."],
    browserslist: ["electron 7.1.13"],
    eslintOptions: {
      cwd: path.join(projectRoot, reposDir, "electron-react-boilerplate"),
      extensions: [".js", ".jsx", ".ts", ".tsx"],
      useEslintrc: false,
      // @ts-expect-error Bug?
      baseConfig: [
        compat.configs["flat/recommended"],
        {
          plugins: {
            "@typescript-eslint": typescriptEslintPlugin,
          },
          languageOptions: {
            globals: {
              ...globals.browser,
              ...globals.node,
            },
            parser: typescriptEslintParser,
            parserOptions: {
              ecmaVersion: 2022,
              sourceType: "module",
            },
          },
          ignores: ["*css.d.ts", "*sass.d.ts", "*scss.d.ts"],
        },
      ],
    },
  },
  {
    name: "handlebars.js",
    location: path.join(projectRoot, reposDir, "handlebars.js"),
    remoteLink: "https://github.com/handlebars-lang/handlebars.js.git",
    targetCommitId: "e6ad93ea01bcde1f8ddaa4b4ebe572dd616abfaa",
    targetGitRef: "v4.7.6",
    filePatterns: ["."],
    eslintOptions: {
      cwd: path.join(projectRoot, reposDir, "handlebars.js"),
      extensions: [".js"],
      useEslintrc: false,
      // @ts-expect-error Bug?
      baseConfig: [
        compat.configs["flat/recommended"],
        {
          languageOptions: {
            parserOptions: {
              ecmaVersion: 2022,
              sourceType: "module",
            },
          },
        },
      ],
    },
  },
  {
    name: "jquery",
    location: path.join(projectRoot, reposDir, "jquery"),
    remoteLink: "https://github.com/jquery/jquery.git",
    targetCommitId: "e1cffdef277fcf543833a20d28cbadcd000ebece",
    targetGitRef: "3.5.1",
    filePatterns: ["src/**/*.js", "test/**/*.js"],
    eslintOptions: {
      cwd: path.join(projectRoot, reposDir, "jquery"),
      extensions: [".js"],
      useEslintrc: false,
      // @ts-expect-error Bug?
      baseConfig: [
        compat.configs["flat/recommended"],
        {
          languageOptions: {
            globals: {
              window: true,
            },
            parserOptions: {
              ecmaVersion: 2022,
              sourceType: "module",
            },
          },
        },
      ],
    },
  },
  {
    name: "preact",
    location: path.join(projectRoot, reposDir, "preact"),
    remoteLink: "https://github.com/preactjs/preact.git",
    targetCommitId: "1834cd70adf5758541d6167ba8c2c42778443d04",
    targetGitRef: "10.4.4",
    filePatterns: ["*.js"],
    eslintOptions: {
      cwd: path.join(projectRoot, reposDir, "preact"),
      extensions: [".js"],
      useEslintrc: false,
      // @ts-expect-error Bug?
      baseConfig: [
        compat.configs["flat/recommended"],
        {
          languageOptions: {
            globals: globals.browser,
            parser: typescriptEslintParser,
            parserOptions: {
              ecmaVersion: 2022,
              sourceType: "module",
              jsx: true,
            },
          },
          ignores: ["test/fixtures", "test/ts/", "*.ts", "dist"],
        },
      ],
    },
  },
  // {
  //   name: "vscode",
  //   location: path.join(projectRoot, reposDir, "vscode"),
  //   remoteLink: "https://github.com/microsoft/vscode.git",
  //   targetCommitId: "cd9ea6488829f560dc949a8b2fb789f3cdc05f5d",
  //   targetGitRef: "1.46.1",
  //   filePatterns: ["./src/vs", "./extensions", "./build"],
  //   browserslist: ["electron 7.3.1"],
  //   eslintOptions: {
  //     cwd: path.join(projectRoot, reposDir, "vscode"),
  //     extensions: [".js", ".ts"],
  //     useEslintrc: false,
  //     // @ts-expect-error Bug?
  //     baseConfig: [
  //       compat.configs['flat/recommended'],
  //       {
  //         languageOptions: {
  //           globals: {
  //             ...globals.node,
  //             ...globals.es2015,
  //             ...globals.browser
  //           },
  //           parser: typescriptEslintParser,
  //           parserOptions: {
  //             ecmaVersion: 6,
  //             sourceType: "module",
  //           }
  //         }
  //       },
  //     ],
  //   },
  // },
  {
    name: "create-react-app",
    location: path.join(projectRoot, reposDir, "create-react-app"),
    remoteLink: "https://github.com/facebook/create-react-app.git",
    targetCommitId: "d2f813f8897ffcd2f0b0d2da75d0c44924c92f4d",
    targetGitRef: "create-react-app@3.4.1",
    filePatterns: ["."],
    eslintOptions: {
      cwd: path.join(projectRoot, reposDir, "create-react-app"),
      extensions: [".js"],
      useEslintrc: false,
      // @ts-expect-error Bug?
      baseConfig: [
        compat.configs["flat/recommended"],
        {
          files: ["**/*.ts?(x)"],
          languageOptions: {
            parser: "@typescript-eslint/parser",
            parserOptions: {
              ecmaVersion: 2022,
              sourceType: "module",
              ecmaFeatures: {
                jsx: true,
              },
              warnOnUnsupportedTypeScriptVersion: true,
            },
          },
          plugins: {
            "@typescript-eslint": typescriptEslintPlugin,
          },
        },
        {
          languageOptions: {
            globals: {
              ...globals.browser,
              ...globals.commonjs,
              ...globals.node,
              ...globals.es2015,
            },
            parser: babelEslintParser,
            parserOptions: {
              ecmaVersion: 2022,
              sourceType: "module",
              ecmaFeatures: {
                jsx: true,
              },
              requireConfigFile: false,
            },
          },
        },
      ],
    },
  },
  {
    name: "aframe",
    location: path.join(projectRoot, reposDir, "aframe"),
    remoteLink: "https://github.com/aframevr/aframe.git",
    targetCommitId: "781b6abb47d572c1e52add53166f35e4a876908c",
    targetGitRef: "v1.0.4",
    filePatterns: ["."],
    eslintOptions: {
      cwd: path.join(projectRoot, reposDir, "aframe"),
      extensions: [".js"],
      useEslintrc: false,
      // @ts-expect-error Bug?
      baseConfig: [
        compat.configs["flat/recommended"],
        {
          ignores: [
            "build/**",
            "dist/**",
            "examples/**/shaders/*.js",
            "**/vendor/**",
          ],
          languageOptions: {
            globals: globals.es2015,
            parserOptions: {
              ecmaVersion: 2022,
              sourceType: "module",
            },
          },
        },
      ],
    },
  },
  {
    name: "pixi.js",
    location: path.join(projectRoot, reposDir, "pixi.js"),
    remoteLink: "https://github.com/pixijs/pixi.js.git",
    targetCommitId: "71c6b3b2061af4a4f3a95a265d46e933b8befc2c",
    targetGitRef: "v5.2.4",
    filePatterns: ["test", "bundles", "packages", "tools"],
    eslintOptions: {
      cwd: path.join(projectRoot, reposDir, "pixi.js"),
      extensions: [".js", ".ts"],
      useEslintrc: false,
      // @ts-expect-error Bug?
      baseConfig: [
        compat.configs["flat/recommended"],
        {
          plugins: {
            "@typescript-eslint": typescriptEslintPlugin,
          },
          languageOptions: {
            globals: {
              ...globals.es2015,
              ...globals.browser,
            },
            parser: typescriptEslintParser,
            parserOptions: {
              ecmaVersion: 2022,
              sourceType: "module",
            },
          },
        },
      ],
    },
  },
];

export async function initRepo(
  { targetCommitId, remoteLink, location }: RepoInfo,
  showLogs = true
) {
  const benchmarksAbsPath = path.join(projectRoot, reposDir);
  if (!existsSync(benchmarksAbsPath)) {
    mkdirSync(benchmarksAbsPath);
  }

  if (showLogs) console.log(`Retrieving ${remoteLink}`);

  const git: SimpleGit = simpleGit();
  // Clone if necessary, else use existing repo
  if (!existsSync(path.join(location, ".git"))) {
    if (showLogs)
      console.log(`${location} not found, proceeding to clone from remote`);
    await git.clone(remoteLink, location);
    git.init();
  }
  await git.cwd(location);
  await git.checkout(targetCommitId);
}

export default repos;
